#pragma once

#include <InputCoreTypes.h>
#include <GenericPlatform/GenericApplicationMessageHandler.h>

enum class EWiiRemoteDeviceButton
{
    WIIREMOTE_BTN_A,
    WIIREMOTE_BTN_B,
    WIIREMOTE_BTN_ONE,
    WIIREMOTE_BTN_TWO,
    WIIREMOTE_BTN_PLUS,
    WIIREMOTE_BTN_MINUS,
    WIIREMOTE_BTN_UP,
    WIIREMOTE_BTN_DOWN,
    WIIREMOTE_BTN_LEFT,
    WIIREMOTE_BTN_RIGHT,
    WIIREMOTE_BTN_HOME,
    
    WIIREMOTE_BTN_COUNT
};

enum class EWiiRemoteDeviceAxes
{
    AXES_IR_X,
    AXES_IR_Y,
    AXES_IR_Z,

    TotalAxisCount
};

struct FWiiRemoteDeviceKey
{
    static const FKey WiiRemoteDevice_A;
    static const FKey WiiRemoteDevice_B;
    static const FKey WiiRemoteDevice_ONE;
    static const FKey WiiRemoteDevice_TWO;
    static const FKey WiiRemoteDevice_PLUS;
    static const FKey WiiRemoteDevice_MINUS;
    static const FKey WiiRemoteDevice_UP;
    static const FKey WiiRemoteDevice_DOWN;
    static const FKey WiiRemoteDevice_LEFT;
    static const FKey WiiRemoteDevice_RIGHT;
    static const FKey WiiRemoteDevice_HOME;

    static const FKey WiiRemoteDevice_IR_X;
    static const FKey WiiRemoteDevice_IR_Y;
    static const FKey WiiRemoteDevice_IR_Z;
};

struct FWiiRemoteDeviceKeyNames
{
    typedef FName Type;

    static const FName WiiRemoteDevice_A;
    static const FName WiiRemoteDevice_B;
    static const FName WiiRemoteDevice_ONE;
    static const FName WiiRemoteDevice_TWO;
    static const FName WiiRemoteDevice_PLUS;
    static const FName WiiRemoteDevice_MINUS;
    static const FName WiiRemoteDevice_UP;
    static const FName WiiRemoteDevice_DOWN;
    static const FName WiiRemoteDevice_LEFT;
    static const FName WiiRemoteDevice_RIGHT;
    static const FName WiiRemoteDevice_HOME;

    static const FName WiiRemoteDevice_IR_X;
    static const FName WiiRemoteDevice_IR_Y;
    static const FName WiiRemoteDevice_IR_Z;
};

struct FWiiRemoteDeviceButtonState
{
    FName Key;
    bool bIsPressed;

    double NextRepeatTime;

    FWiiRemoteDeviceButtonState()
        : Key(NAME_None),
        bIsPressed(false),
        NextRepeatTime(0.0)
    {
    }
};

struct FWiiRemoteDeviceAxisState
{
    FName Axis;
    float State;

    FWiiRemoteDeviceAxisState()
        :Axis(NAME_None),
        State(0.f)
    {

    }
};

struct FWiiRemoteDeviceState
{
    bool bIsConnected;

    FWiiRemoteDeviceButtonState Buttons[(int32)EWiiRemoteDeviceButton::WIIREMOTE_BTN_COUNT];
    FWiiRemoteDeviceAxisState CapaAxes[(int32)EWiiRemoteDeviceAxes::TotalAxisCount];

    FWiiRemoteDeviceState()
        :bIsConnected(false)
    {
        for (FWiiRemoteDeviceButtonState& Button : Buttons)
        {
            Button.bIsPressed = false;
            Button.NextRepeatTime = 0.0f;
        }

        CapaAxes[(int32)EWiiRemoteDeviceAxes::AXES_IR_X].Axis = FWiiRemoteDeviceKeyNames::WiiRemoteDevice_IR_X;
        CapaAxes[(int32)EWiiRemoteDeviceAxes::AXES_IR_Y].Axis = FWiiRemoteDeviceKeyNames::WiiRemoteDevice_IR_Y;
        CapaAxes[(int32)EWiiRemoteDeviceAxes::AXES_IR_Z].Axis = FWiiRemoteDeviceKeyNames::WiiRemoteDevice_IR_Z;
    }
};